'use client';

import { useToast } from '@/hooks/use-toast';
import { authClient } from '@/lib/auth-client';
import { genProductImageKey } from '@/lib/cos';
import { result } from '@/lib/utils';
import { useCosClient } from '@/providers/cos-provider';
import { createProduct, updateProduct } from '@/service/actions/product';
import { productFormSchema } from '@/service/actions/schema/product';
import type { ProductType } from '@/service/type/product';
import { zodResolver } from '@hookform/resolvers/zod';
import { useState, useTransition } from 'react';
import { useForm } from 'react-hook-form';
import type { z } from 'zod';
import ImageUploader from '../common/image-uploader';
import QueryImage from '../common/query-image';
import { Button } from '../ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '../ui/dialog';
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '../ui/form';
import { Input } from '../ui/input';
import { Label } from '../ui/label';
import ImagePopover from './image-popover';

type CreateEditProductProps =
  | {
      type: 'new';
      button: React.ReactNode;
    }
  | {
      type: 'edit';
      button: React.ReactNode;
      preData: ProductType;
    };

const ProductForm = (
  props: CreateEditProductProps & {
    setOpen: (open: boolean) => void;
  },
) => {
  const { data: session } = authClient.useSession();
  const { toast } = useToast();
  const [isPending, startTransition] = useTransition();
  const cosClient = useCosClient();
  const [imageKeys, setImageKeys] = useState<string[]>(
    props.type === 'edit' ? [...props.preData.imageKeys] : [],
  );
  const form = useForm<z.infer<typeof productFormSchema>>({
    resolver: zodResolver(productFormSchema),
    defaultValues:
      props.type === 'edit'
        ? {
            name: props.preData.name,
            price: props.preData.price,
            description: props.preData.description ?? '',
          }
        : {
            name: '',
            price: '0',
            description: '',
          },
  });

  const updateImageKeys = async (keys: string[], isDelete: boolean) => {
    if (props.type === 'new') {
      if (isDelete) {
        setImageKeys((pre) => pre.filter((k) => !keys.includes(k)));
        cosClient?.delete(keys);
        toast({
          title: '删除成功',
        });
      } else setImageKeys((pre) => [...pre, ...keys]);
      return result();
    }
    const updateServer = (keys: string[]) => {
      return updateProduct({
        id: props.preData.id,
        name: props.preData.name,
        price: props.preData.price,
        description: props.preData.description ?? '',
        imageKeys: keys,
      }).then((result) => {
        !result.error && setImageKeys(keys);
        return result;
      });
    };
    const res = isDelete
      ? await updateServer(imageKeys.filter((k) => !keys.includes(k)))
      : await updateServer([...imageKeys, ...keys]);
    if (isDelete) {
      toast({
        variant: res.error ? 'destructive' : 'default',
        title: `删除${res.error ? '失败' : '成功'}`,
      });
      !res.error && cosClient?.delete(keys);
    } else if (res.error)
      toast({
        title: '同步图片失败',
        variant: 'destructive',
      });
    return res.error ? result(res.error, res.error.message) : result();
  };

  const onSubmit = async (values: z.infer<typeof productFormSchema>) => {
    startTransition(async () => {
      const { error } =
        props.type === 'new'
          ? await createProduct({
              name: values.name,
              price: values.price,
              description: values.description,
              imageKeys,
            })
          : await updateProduct({
              id: props.preData.id,
              name: values.name,
              price: values.price,
              description: values.description,
              imageKeys,
            });
      if (error) {
        toast({
          variant: 'destructive',
          title: error.message,
        });
        return;
      }
      toast({
        title: props.type === 'new' ? '创建成功' : '更新成功',
      });
      props.setOpen(false);
      props.type === 'new' && setImageKeys([]);
      form.reset();
    });
  };
  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-3">
        <FormField
          control={form.control}
          name="name"
          render={({ field }) => (
            <FormItem>
              <FormLabel>外卖名称</FormLabel>
              <FormControl>
                <Input placeholder="外卖名称" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          control={form.control}
          name="price"
          render={({ field }) => (
            <FormItem>
              <FormLabel>价格</FormLabel>
              <FormControl>
                <Input placeholder="价格" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          control={form.control}
          name="description"
          render={({ field }) => (
            <FormItem>
              <FormLabel>描述</FormLabel>
              <FormControl>
                <Input placeholder="描述" {...field} />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <div className="space-y-2">
          <Label>外卖图片</Label>
          <div className="grid grid-cols-3 gap-2 max-h-36 overflow-auto scrollbar-none">
            {imageKeys.map((key) => (
              <ImagePopover
                key={key}
                imageKey={key}
                onDelete={() => updateImageKeys([key], true)}
              >
                <QueryImage
                  key={key}
                  imageKey={key}
                  wrapperClassName="h-24 w-fit"
                  imgClassName="h-full w-full object-cover"
                />
              </ImagePopover>
            ))}
          </div>
        </div>
        <div className="flex justify-end pt-2">
          <ImageUploader
            genImageKey={() => genProductImageKey(session?.user.id ?? '-1')}
            onUploaded={(keys) => updateImageKeys(keys, false)}
            button={<Button>上传图片</Button>}
          />
        </div>
        <div className="flex justify-between pt-5">
          <Button
            type="button"
            variant="secondary"
            onClick={() => {
              props.setOpen(false);
              form.reset();
              if (props.type === 'new') {
                imageKeys.length && cosClient?.delete(imageKeys);
                setImageKeys([]);
              }
            }}
          >
            取消
          </Button>
          <Button type="submit" disabled={isPending}>
            {isPending && <span className="animate-spin i-ri-loader-4-line" />}
            {props.type === 'new' ? '创建' : '保存'}
          </Button>
        </div>
      </form>
    </Form>
  );
};

export default function CreateEditProduct(props: CreateEditProductProps) {
  const [open, setOpen] = useState(false);

  return (
    <Dialog open={open}>
      <DialogTrigger asChild onClick={() => setOpen(true)}>
        {props.button}
      </DialogTrigger>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>
            {props.type === 'new' ? '新建外卖' : '编辑外卖'}
          </DialogTitle>
          <DialogDescription>
            {props.type === 'new'
              ? '请填写以下信息以创建新的外卖'
              : '请填写以下信息以编辑外卖'}
          </DialogDescription>
        </DialogHeader>
        <ProductForm {...props} setOpen={setOpen} />
      </DialogContent>
    </Dialog>
  );
}
